﻿using System.Collections.Generic;
using UnityEngine;

namespace LightGameLibs
{

    /// <summary>
    /// 继承这个泛型模板类，即可创建一个可序列化的字典类（用于持久化数据存储）
    /// </summary>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TValue"></typeparam>
    public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
    {

        [SerializeField]
        private List<TKey> m_keys = new List<TKey>();
        [SerializeField]
        private List<TValue> m_values = new List<TValue>();

        public new TValue this[TKey key]
        {
            get
            {
                return base[key];
            }
            set
            {
                if (!Application.isPlaying && null != m_keys && null != m_values)
                {
                    bool isFound = false;
                    int i = 0;
                    for (int length = m_keys.Count; i < length; i++)
                    {
                        if (key.Equals(m_keys[i]))
                        {
                            isFound = true;
                            break;
                        }
                    }

                    if (isFound)
                    {
                        m_values[i] = value;
                    }
                }
                base[key] = value;
            }
        }

        public void OnBeforeSerialize()
        {
            for (int i = 0, length = m_keys.Count; i < length; i++)
            {
                TValue value;
                if (this.TryGetValue(m_keys[i], out value) && i < m_values.Count)
                {
                    m_values[i] = value;
                }
            }
        }

        public void OnAfterDeserialize()
        {
            if (m_keys.Count != m_values.Count)
            {
                Debug.LogWarning("Keys Values Count Unequal");
            }

            base.Clear();
            int count = Mathf.Min(m_keys.Count, m_values.Count);
            for (int i = 0; i < count; ++i)
            {
                if (this.ContainsKey(m_keys[i]))
                {
                    Debug.LogWarning("Key Already Exist");
                    continue;
                }

                base.Add(m_keys[i], m_values[i]);
            }
        }

        public new void Add(TKey key, TValue value)
        {
            base.Add(key, value);
            m_keys.Add(key);
            m_values.Add(value);
        }

        public new void Clear()
        {
            base.Clear();
            m_keys.Clear();
            m_values.Clear();
        }

        public new void Remove(TKey key)
        {
            m_values.Remove(this[key]);
            m_keys.Remove(key);
            base.Remove(key);
        }

        public Dictionary<TKey, TValue> GetRawDict()
        {
            var rawDict = new Dictionary<TKey, TValue>();
            foreach (var item in this)
            {
                rawDict.Add(item.Key, item.Value);
            }
            return rawDict;
        }
    }
}